import axios from 'axios'
import { Toast } from 'vant'
import store from '@/store/index.js'
import router from '@/router/index.js'
// 调用 axios.create() 方法，创建 axios 的实例对象
const request = axios.create({
  // 请求根路径
  baseURL: 'http://www.liulongbin.top:8000'
})

// 1.拦截器的挂载, 一定要到 request 实例创建之后
// 2.由于我们在项目中是基于 request 实例对象发起的请求, 因此, 拦截器一定要挂载给request, 而不是 axios

// 添加请求拦截器
request.interceptors.request.use(
  // 在请求拦截器的第一个 function中 形参config 就是你每次请求的相关的配置选项
  // 比如请求方式,请求地址,请求头
  function (config) {
    Toast.loading({
      message: '加载中...',
      duration: 0
    })

    // 从 vuex 中获取 token 的值
    const tokenStr = store.state.tokenInfo.token
    if (tokenStr) {
      config.headers.Authorization = 'Bearer ' + tokenStr
    }
    return config
  },
  function (error) {
    Toast.clear()
    return Promise.reject(error)
  }
)

// 添加响应拦截器
request.interceptors.response.use(
  function (response) {
    // 对响应数据做点什么
    Toast.clear()
    return response
  },
  // 对响应错误做点什么
  async function (error) {
    Toast.clear()
    // 从vuex 中获取 refresh_token 的值
    const refreshToken = store.state.tokenInfo.refresh_token
    // console.log(error)
    // 判断响应码的状态码是否为401
    // 如果有值为401,且refreshToken有值,则执行换取token
    if (error.response.status === 401 && refreshToken) {
      // async和await接收结果,try和catch接收await错误
      try {
        // 1大坑,不在这里直接使用request对象,来发起换取Token请求
        // 因为请求拦截器发送了request请求,会再次传递过期的token请求
        const { data: res } = await axios({
          method: 'PUT',
          // 2大坑,给完整的URL地址,因为axios没有配置baseURL
          url: 'http://www.liulongbin.top:8000/v1_0/authorizations',
          headers: {
            // 3大坑,格式必须是Bearrer xxx(空格别忘)
            Authorization: 'Bearer ' + refreshToken
          }
        })
        // 1.用新token替换vuex和localStorage中的旧token
        store.commit('updateTokenInfo', { token: res.data.token, refresh_token: refreshToken })
        // 2.继续完成上次失败的那个请求
        // 请求失败会触发请求失败的拦截器,就是响应拦截器第二个响应错误的函数
        // 在error.config就有上次失败请求的那个结果(请求地址,参数,请求方式)
        return request(error.config)
      } catch {
        // 只要能够执行 catch 中代码. 证明token 和 refresh_token都过期
        // 1.强制用户跳转到登录页
        router.replace('/login?pre=' + router.currentRoute.fullPath)
        // 2.清空vuex和localStorge中的数据
        store.commit('cleanState')
      }
    }

    return Promise.reject(error)
  }
)
export default request
